package com.newworld.basketballfire.main.business;

import com.newworld.basketballfire.main.api.Const;
import com.newworld.basketballfire.main.api.ErrorCode;
import com.newworld.basketballfire.main.bean.NoteListParam;
import com.newworld.basketballfire.main.dao.NoteDao;
import com.newworld.basketballfire.main.utils.CommonUtils;
import com.newworld.basketballfire.main.utils.InputChecker;
import com.newworld.basketballfire.service.exception.ServiceException;
import com.newworld.basketballfire.service.model.ListResult;
import com.newworld.basketballfire.service.model.Note;
import com.newworld.basketballfire.service.model.NoteParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by George on 2019/4/21.
 * NoteBusiness
 */
@Component
public class NoteBusiness {

    private static Logger logger = LoggerFactory.getLogger(NoteBusiness.class);

    @Autowired
    private NoteDao noteDao;

    public Note addNote(NoteParams noteParams) throws ServiceException {
        Note note = getNoteByNoteParams(noteParams);

        checkNote(note);

        note.setId(CommonUtils.getUUID());
        note.setCreateTime(CommonUtils.getCurrentTime());
        note.setLastUpdateTime(CommonUtils.getCurrentTime());
        note.setVersion(Const.DEFAULT_VERSION);

        noteDao.addNote(note);
        return note;
    }

    private void checkNote(Note note) throws ServiceException {
        if (StringUtils.isEmpty(note.getName())) {
            logger.error("name is null or empty.");
            throw new ServiceException(HttpStatus.BAD_REQUEST, ErrorCode.INVALID_PARAMS, "name is null or empty.");
        }

        if (note.getName().length() > 256 || note.getName().length() < 1) {
            logger.error("name length is over range [1, 256].");
            throw new ServiceException(HttpStatus.BAD_REQUEST, ErrorCode.INVALID_PARAMS, "name length is over range [1, 256].");
        }

        if (!StringUtils.isEmpty(note.getContent()) && note.getContent().length() > 500) {
            logger.error("content length is over range [0, 500].");
            throw new ServiceException(HttpStatus.BAD_REQUEST, ErrorCode.INVALID_PARAMS, "content length is over range [0, 500].");
        }
    }

    private Note getNoteByNoteParams(NoteParams noteParams) {
        Note note = new Note();
        note.setId(noteParams.getId());
        note.setName(noteParams.getName());
        note.setContent(noteParams.getContent());
        note.setDate(noteParams.getDate());
        return note;
    }

    public Note updateNote(NoteParams noteParams) throws ServiceException {
        Note note = getNoteByNoteParams(noteParams);
        checkNote(note);

        Note oldNote = noteDao.getNote(note.getId());
        if (oldNote == null || !oldNote.getId().equals(note.getId())) {
            logger.error("note is not exist or invalid.");
            throw new ServiceException(HttpStatus.BAD_REQUEST, ErrorCode.INVALID_PARAMS, "note is not exist or invalid.");
        }

        note.setVersion(oldNote.getVersion());
        note.setLastUpdateTime(CommonUtils.getCurrentTime());

        noteDao.updateNote(note);

        return note;
    }

    public Note getNote(String id) throws ServiceException {
        return noteDao.getNote(id);
    }

    public void deleteNote(String id) throws ServiceException {
        noteDao.deleteNote(id);
    }

    public ListResult<Note> getNoteList(NoteListParam noteListParam) throws ServiceException {
        InputChecker.checkPageSizeAndNo(noteListParam.getPageNo(), noteListParam.getPageSize());

        int curIndex = (noteListParam.getPageNo() - 1) * noteListParam.getPageSize();
        noteListParam.setCurIndex(curIndex);

        ListResult<Note> duesListResult = new ListResult<>();
        duesListResult.setPageSize(noteListParam.getPageSize());
        duesListResult.setPageNo(noteListParam.getPageNo());

        int totalCnt = noteDao.getNoteListTotalCnt(noteListParam);
        duesListResult.setTotalCnt(totalCnt);

        List<Note> notes;
        if (totalCnt > 0) {
            notes = noteDao.getNoteList(noteListParam);
        } else {
            notes = new ArrayList<>();
        }
        duesListResult.setData(notes);

        return duesListResult;
    }
}
